﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using System.Xml.Serialization;
using GUIServerConnectorAPI;
using AppConfig;
using ApplicationConfiguration;
using Logging;

namespace GUIServerConnector
{
    public class GUIServerConnectorController
    {
        private static readonly SimpleLogger logger = SimpleLogger.getLogger(typeof(GUIServerConnectorController));

        private static TcpChannel channel;

        /// <summary>
        /// Binds the remoting capable objects using a tcp channel configured with the hostName and port specified in the configuration
        /// </summary>
        public static void startServices()
        {
            if (channel != null)
                throw new InvalidOperationException(Strings.ServicesAlreadyRunning);

            logger.info("Reading GUI connector configuration...");
            AppConfiguration appConfiguration = AppConfiguration.getInstance();
            int port = Int32.Parse(appConfiguration.getProperty("GUIServerConnector", "port"));
            string baseContextPath = GUIServerConnectorAPI.GUIServerConnector.contextPath;
            logger.info("GUI connector port: " + port);
            logger.info("GUI connector base context path: " + baseContextPath);

            logger.info("Registering TCP channel for GUI connector...");
            channel = new TcpChannel(port);
            ChannelServices.RegisterChannel(channel, true);
            startService(baseContextPath, typeof(Authenticator), typeof(IAuthenticator));
            startService(baseContextPath, typeof(ServerInterface), typeof(IServerInterface));
            startService(baseContextPath, typeof(ManagerInterface), typeof(IManagerInterface));
            logger.info("GUI connector services succesfully started");
        }

        private static void startService(string baseContextPath, Type serviceType, Type serviceInterfaceType)
        {
            string contextPath = baseContextPath + "/" + serviceInterfaceType.Name;
            RemotingConfiguration.RegisterWellKnownServiceType(serviceType, contextPath, WellKnownObjectMode.SingleCall);
            logger.info("Registered service \"" + serviceType.FullName + "\". Context path: " + contextPath);
        }

        /// <summary>
        /// Unbinds the remoting capable objects from the tcp channel
        /// </summary>
        public static void stopServices()
        {
            if (channel == null)
                throw new InvalidOperationException(Strings.ServicesNotRunning);
            logger.info("Unregistering TCP channel for GUI connector...");
            ChannelServices.UnregisterChannel(channel);
            channel = null;
            logger.info("GUI connector services succesfully stopped");
        }
    }
}
